
%include <std_string.i>

#define SWIG_SHARED_PTR_NAMESPACE std
#define SWIG_SHARED_PTR_SUBNAMESPACE tr1
%include <boost_shared_ptr.i>

SWIG_SHARED_PTR(SignalData, biosignal::SignalData)
SWIG_SHARED_PTR(DataFrame, biosignal::DataFrame)
SWIG_SHARED_PTR(Montage, biosignal::montage::Montage)

%{
#include <string>
#include <list>
#include <biosignal.h>

using namespace biosignal;
using namespace biosignal::montage;
%}

struct Color {
	unsigned char R;
	unsigned char G;
	unsigned char B;
	unsigned char A;
};


class RefChannel: public Channel {
	RefChannel(SourceSignal::SourceSignal_sptr source);
};

class BipolarChannel : public Channel {
public:
	BipolarChannel(std::string source1, std::string source2);
	std::string source1() const;
	std::string source2() const;
};


class Montage {
public:
	Montage(const BioSignal * biosignal);
	void addChannel(Channel * channel);
	const std::list< ChannelType >& channels() const;
};

class SourceSignalType {
public:
	SourceSignalType();
	string type() const {return m_type;}
	virtual const Position& get_std_position(string label) const = 0;

};

class EEGSignalType : public SourceSignalType {
public:
	EEGSignalType();
	virtual const Position& get_std_position(string label) const;

};


class SourceSignal
{
public:
	typedef std::tr1::shared_ptr< SourceSignal > SourceSignal_sptr;
	typedef std::tr1::weak_ptr< SourceSignal > SourceSignal_wptr;
	SourceSignal();
	SourceSignal(string label, string transducer_type="",
			string physical_dimension="", string filter_information="");

	string label() const;
	void label( string label );

	string transducer_type() const;
	string physical_dimension() const;
	string filter_information() const;
	double sample_rate() const;
	bool enabled() const;

	const Position& position() const;
	const SourceSignalType* type() const;
	void position(const Position& position);
	void type(SourceSignalType* type);
};


class SignalData {
public:
	virtual void value(unsigned int sample_nr, double value) = 0;
	virtual double value(unsigned int sample_nr) const = 0;
	virtual int size() const = 0;
	const SourceSignal* signal_info() const;

	DataIterator begin() const;
	DataIterator end() const;
};



class DataFrame
{
public:
	TimePeriod time_period() const;
	void time_period( TimePeriod time);

	shared_ptr<const montage::Montage> montage() const;
	const std::vector< shared_ptr<SignalData> >& signal_source_data() const;
	shared_ptr<const SignalData> signal_source_data(std::string signal_source_label) const;
};


class TimeOffset;
class TimePoint {
public:
	TimePoint();
	explicit TimePoint(int year, int month, int day, int hour = 0, int minute = 0,
			int second = 0, int useconds = 0);
	TimePoint& operator=(const TimePoint& rhs);
	TimePoint& operator+=(const TimeOffset& rhs);
	TimePoint& operator-=(const TimeOffset& rhs);
	TimePoint operator+(const TimeOffset& time_duration) const;
	TimePoint operator-(const TimeOffset& time_duration) const;
	TimeOffset operator-(const TimePoint& other) const;
	bool operator==(const TimePoint &other) const;
	bool operator!=(const TimePoint &other) const;

	bool operator>=(const TimePoint &other) const;
	bool operator<(const TimePoint &other) const;

	int year() const;
	int month() const;
	int day() const;
	int hour() const;
	int minute() const;
	int second() const;

};

class TimeOffset {
public:
	TimeOffset(int years = 0, int months = 0, int days = 0, int hours = 0,
			int minutes = 0, int seconds = 0, int microseconds = 0);
	TimeOffset& operator=(const TimeOffset& rhs);
	TimeOffset operator+(const TimeOffset& other);
	TimeOffset operator-(const TimeOffset& other);
	bool operator==(const TimeOffset &other) const;
	bool operator!=(const TimeOffset &other) const;

	int days() const;
	int hours() const;
	int minutes() const;
	int seconds() const;
	int microseconds() const;

	long full_days() const;
	long full_hours() const;
	long full_minutes() const;
	long full_seconds() const;
	long total_microseconds() const;

	bool is_negative() const;
	static TimeOffset Seconds(double seconds);

};

class TimePeriod {
public:
	TimePeriod();
	TimePeriod(TimePoint date_time, TimeOffset duration);
	/*
	 * TimePeriod : [begin, end)
	 */
	TimePeriod(TimePoint begin, TimePoint end);
	TimePoint begin() const;
	TimePoint end() const;

	TimeOffset duration() const;
	bool contains(const TimePoint& time_point) const;
	bool contains(const TimePeriod& time_period) const;
	
	void duration(TimeOffset duration);
	void move(TimeOffset offset);
	void begin(TimePoint begin);

};

struct Data {
	double* data;
	int values;
	string label;
	double sample_rate;
};

class SignalSlice
{
public:
	shared_ptr<const montage::Montage> montage() const;
	std::list<Data> all_data() const;
	
};

class BioSignal
{
public:
	BioSignal(const char* file_name);

	const SignalsGroup& signals_group() const;

	SignalSlice signal_slice( TimePeriod time_period ) const throw (BadTimePeriod);
	SignalSlice signal_slice( TimeOffset start, TimeOffset end ) const throw (BadTimePeriod);
	SignalSlice signal() const;

	TimePeriod recording_time() const;


	shared_ptr<const montage::Montage> ref_montage() const;
	shared_ptr<const montage::Montage> avg_ref_montage() const;

      virtual void show_header_info(std::ostream& os) const = 0;
      virtual long get_nr_dataframes() const = 0;
      virtual TimePeriod dataframe_time_period(TimePoint time) const throw (BadTimePoint) = 0;


};


BioSignal* load( std::string file_name );

std::string version();
